#include "spi_driver.h"
#include "driver/spi_master.h"
#include "driver/gpio.h"
#include "esp_log.h"

#define TAG "SPI_DRIVER"

static int clock_speed_hz = SPI_DEFAULT_FREQUENCY;

void spi_set_clock_speed(int speed) {
    ESP_LOGI(TAG, "SPI clock speed=%d MHz", speed / 1000000);
    clock_speed_hz = speed;
}

void spi_init_bus(int mosi, int miso, int sclk, spi_host_device_t spi_host) {
    spi_bus_config_t buscfg = {
        .mosi_io_num = mosi,
        .miso_io_num = miso,
        .sclk_io_num = sclk,
        .quadwp_io_num = -1,
        .quadhd_io_num = -1,
        .max_transfer_sz = 0,
        .flags = 0
    };
    ESP_ERROR_CHECK(spi_bus_initialize(spi_host, &buscfg, SPI_DMA_CH_AUTO));
}

void spi_add_device(spi_device_handle_t *handle, int cs) {
    spi_device_interface_config_t devcfg = {
        .clock_speed_hz = clock_speed_hz,
        .spics_io_num = cs,
        .queue_size = 1
    };
    ESP_ERROR_CHECK(spi_bus_add_device(HOST_ID, &devcfg, handle));
}

bool spi_write_byte(spi_device_handle_t handle, const uint8_t *data, size_t length) {
    esp_err_t ret;
    spi_transaction_t t;

    if (!data || 0 == length ) {
        return 0;
    }             //no need to send anything
    memset(&t, 0, sizeof(t));           //Zero out the transaction
    t.length = length * 8;              //Len is in bytes, transaction length is in bits.
    t.tx_buffer = data;                 //Data
    t.user = NULL;                
    ret = spi_device_polling_transmit(handle, &t);  //Transmit!
    assert(ret==ESP_OK);            //Should have had no issues.
    return 1;
}

bool spi_read_byte(spi_device_handle_t handle, uint8_t *data, size_t length) {
    spi_transaction_t t;

    if (!data || 0 == length ) {
        return 0;
    }             //no need to send anything
    memset(&t, 0, sizeof(t));
    t.length = length * 8;
    t.flags = SPI_TRANS_USE_RXDATA;
    t.user = NULL;
    esp_err_t ret = spi_device_polling_transmit(handle, &t);
    assert( ret == ESP_OK );
    memcpy(data, t.rx_data, length);
}
